package com.tools.common.object.json.deserializer;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.tools.common.object.Note;
import com.tools.common.object.ObjKit;
import com.tools.common.object.json.JsonKit;
import com.tools.web.interceptor.auth._common.MultipleAuthUser;
import com.tools.web.interceptor.auth._common.SingleAuthUser;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 单用户在线记录的 AuthUser 对象的序列化
 * */
@Note("AuthUser 类型对象的处理器")
public class AuthUserTypeHandler {

    private AuthUserTypeHandler() {}


    /**
     * TODO 以后可以用流模式改进
     * */
    @Note("单用户在线记录的 AuthUser 对象的序列化")
    public static StdDeserializer<SingleAuthUser> singleAuthUserDeserializer() {
        return new StdDeserializer<SingleAuthUser>(SingleAuthUser.class) {
            @Override
            public SingleAuthUser deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonNode rootNode = JsonKit.readToNode(jsonParser);
                Object userId = JsonKit.jsonNodeToBasicValue(rootNode.get("userId"));
                String userTypeClassname = rootNode.get("userTypeClass").asText();
                Class<?> userTypeClass = ObjKit.getObjectClass(userTypeClassname);
                String userJson = rootNode.get("user").toString();
                Object user = JsonKit.toEntity(userJson, userTypeClass);
                JsonNode roleKeyMapNode = rootNode.get("roleKeyMap");
                Map roleKeyMap = null;
                if(roleKeyMapNode != null) {
                    roleKeyMap = JsonKit.toEntity(roleKeyMapNode.toString(), HashMap.class);
                }
                JsonNode permKeyMapNode = rootNode.get("permKeyMap");
                Map permKeyMap = null;
                if(permKeyMapNode != null) {
                    permKeyMap = JsonKit.toEntity(permKeyMapNode.toString(), HashMap.class);
                }
                JsonNode routerListNode = rootNode.get("routerList");
                List routerList = null;
                if(routerListNode != null) {
                    routerList = JsonKit.toEntity(routerListNode.toString(), ArrayList.class);
                }
                JsonNode customDataNode = rootNode.get("customData");
                Map<String, Object> customData = null;
                if(customDataNode != null) {
                    customData = JsonKit.toEntity(customDataNode.toString(), new TypeReference<HashMap<String, Object>>() {});
                }
                String uuid = rootNode.get("uuid").asText();
                String loginDeviceType = rootNode.get("loginDeviceType").asText();
                JsonNode loginUserTypeNode = rootNode.get("loginUserType");
                String loginUserType = null;
                if(loginUserTypeNode != null) {
                    loginUserType = loginUserTypeNode.asText();
                }
                SingleAuthUser authUser = new SingleAuthUser(userId, loginDeviceType, user, roleKeyMap, permKeyMap, routerList);
                authUser.setCustomData(customData);
                authUser.setUserTypeClass(userTypeClass);
                authUser.setUuid(uuid);
                authUser.setLoginUserType(loginUserType);
                return authUser;
            }
        };
    }



    @Note("单用户在线记录的 AuthUser 对象的序列化")
    public static StdDeserializer<MultipleAuthUser> multipleAuthUserStdDeserializer() {
        return new StdDeserializer<MultipleAuthUser>(MultipleAuthUser.class) {
            @Override
            public MultipleAuthUser deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonNode rootNode = JsonKit.readToNode(jsonParser);
                String userTypeClassname = rootNode.get("userTypeClass").asText();
                Class<?> userTypeClass = ObjKit.getObjectClass(userTypeClassname);
                String userJson = rootNode.get("user").toString();
                Object user = JsonKit.toEntity(userJson, userTypeClass);
                Object userId = JsonKit.jsonNodeToBasicValue(rootNode.get("userId"));
                JsonNode permKeyMapNode = rootNode.get("permKeyMap");
                Map permKeyMap = null;
                if(permKeyMapNode != null) {
                    permKeyMap = JsonKit.toEntity(permKeyMapNode.toString(), HashMap.class);
                }
                JsonNode roleKeyMapNode = rootNode.get("roleKeyMap");
                Map roleKeyMap = null;
                if(roleKeyMapNode != null) {
                    roleKeyMap = JsonKit.toEntity(roleKeyMapNode.toString(), HashMap.class);
                }
                JsonNode customDataNode = rootNode.get("customData");
                Map<String, Object> customData = null;
                if(customDataNode != null) {
                    customData = JsonKit.toEntity(customDataNode.toString(), new TypeReference<HashMap<String, Object>>() {});
                }
                JsonNode routerListNode = rootNode.get("routerList");
                List routerList = null;
                if(routerListNode != null) {
                    routerList = JsonKit.toEntity(routerListNode.toString(), ArrayList.class);
                }
                String recordMapJson = rootNode.get("keyAndDeviceAndLoginRecordMap").toString();
                ConcurrentHashMap<String, LinkedHashMap<String, Long>> keyAndDeviceAndLoginRecordMap =
                        JsonKit.toEntity(recordMapJson, new TypeReference<ConcurrentHashMap<String, LinkedHashMap<String, Long>>>() {});
                String loginDeviceType = rootNode.get("loginDeviceType").asText();
                String uuid = rootNode.get("uuid").asText();
                JsonNode loginUserTypeNode = rootNode.get("loginUserType");
                String loginUserType = null;
                if(loginUserTypeNode != null) {
                    loginUserType = loginUserTypeNode.asText();
                }
                MultipleAuthUser authUser = new MultipleAuthUser(userId, loginDeviceType, user, roleKeyMap, permKeyMap, routerList);
                ObjKit.setFieldValue(authUser, "keyAndDeviceAndLoginRecordMap", keyAndDeviceAndLoginRecordMap);
                authUser.setCustomData(customData);
                authUser.setUserTypeClass(userTypeClass);
                authUser.setUuid(uuid);
                authUser.setLoginUserType(loginUserType);
                return authUser;
            }
        };
    }


    @Note("多用户在线记录的 AuthUser 对象的序列化")
    public static JsonSerializer<MultipleAuthUser> multipleAuthUserSerializer() {
        return new JsonSerializer<MultipleAuthUser>() {
            @Override
            public void serialize(MultipleAuthUser multipleAuthUser, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                jsonGenerator.writeStartObject();
                Object keyAndDeviceAndLoginRecordMap = ObjKit.getFieldValue(multipleAuthUser, "keyAndDeviceAndLoginRecordMap");
                jsonGenerator.writeObjectField("keyAndDeviceAndLoginRecordMap", keyAndDeviceAndLoginRecordMap);
                jsonGenerator.writeStringField("uuid", ObjKit.toStringNullString(multipleAuthUser.getUuid()));
                jsonGenerator.writeObjectField("userId", multipleAuthUser.getUserId());
                jsonGenerator.writeStringField("loginDeviceType", ObjKit.toStringNullString(multipleAuthUser.getLoginDeviceType()));
                jsonGenerator.writeStringField("loginUserType", ObjKit.toStringNullString(multipleAuthUser.getLoginUserType()));
                Class<?> userTypeClass = multipleAuthUser.getUserTypeClass();
                jsonGenerator.writeStringField("userTypeClass", userTypeClass != null ? userTypeClass.getName() : null);
                jsonGenerator.writeObjectField("user", multipleAuthUser.getUser());
                jsonGenerator.writeObjectField("roleKeyMap", multipleAuthUser.getRoleKeyMap());
                jsonGenerator.writeObjectField("permKeyMap", multipleAuthUser.getPermKeyMap());
                jsonGenerator.writeObjectField("routerList", multipleAuthUser.getRouterList());
                jsonGenerator.writeObjectField("customData", multipleAuthUser.getCustomData());
                jsonGenerator.writeEndObject();
            }
        };
    }

}
